package com.ashes.brave.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.ashes.belife.common.config.RedisCache;
import com.ashes.belife.common.exception.AshesException;
import com.ashes.belife.common.utils.*;
import com.ashes.brave.mapper.UserSysMapper;
import com.ashes.brave.service.MenuSysService;
import com.ashes.brave.service.UserSysService;
import com.ashes.oppo.po.SysAshesUserPO;
import com.ashes.oppo.vo.SysAshesUserVO;
import com.ashes.security.frame.LoginUser;
import com.ashes.security.frame.RequestTokenUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author chengxuhui
 * @description 用户模块实现类
 */
@Slf4j
@Service
public class UserSysServiceImpl implements UserSysService {
    @Autowired
    private UserSysMapper userSysMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private MenuSysService menuSysService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public Result queryUserListData(SysAshesUserVO sysAshesUserVO, int page, int limit) {
        log.info("请求接口queryUserListData入参{},{},{}", sysAshesUserVO, page, limit);
        PageHelper.startPage(page, limit+1);
        List<SysAshesUserPO> sysAshesUserPOS = userSysMapper.queryUserListData(sysAshesUserVO);
        PageInfo<SysAshesUserPO> pageInfo = new PageInfo<>(sysAshesUserPOS);
        //统一记录结果集日志
        log.info("请求接口queryUserListData返回结果{}", pageInfo);
        return Result.ok(pageInfo);
    }

    @Override
    public Result addUserInfo(HttpServletRequest request, SysAshesUserVO sysAshesUserVO) {
        log.info("请求接口addUserInfo入参{}", sysAshesUserVO);
        //对数据进行封装处理
        sysAshesUserVO.setLoginIp(IpUtil.getClientIp(request));
        String password = sysAshesUserVO.getPassword();
        sysAshesUserVO.setUserId(new BigDecimal(IdUtil.getSnowflake().nextId()));
        sysAshesUserVO.setPassword(MD5Util.encrypt(password));
        sysAshesUserVO.setDelFlag("0");
        sysAshesUserVO.setStatus("0");
        sysAshesUserVO.setUserType("01");
        sysAshesUserVO.setCreateTime(DateUtil.now());
        Integer count = userSysMapper.addUserInfo(sysAshesUserVO);
        if (count == 0) {
            throw new AshesException("添加失败");
        }
        //统一记录结果集日志
        log.info("请求接口addUserInfo返回结果{}", count);
        return Result.ok(count);
    }

    @Override
    public Result updateUserInfo(HttpServletRequest request, SysAshesUserVO sysAshesUserVO) {
        log.info("请求接口updateUserInfo入参{}", sysAshesUserVO);
        sysAshesUserVO.setLoginIp(IpUtil.getClientIp(request));
        Integer count = userSysMapper.updateUserInfo(sysAshesUserVO);
        if (count == 0) {
            throw new AshesException("添加失败");
        }
        //统一记录结果集日志
        log.info("请求接口updateUserInfo返回结果{}", count);
        return Result.ok(count);
    }

    @Override
    public Result deleteUserInfo(SysAshesUserVO sysAshesUserVO) {
        log.info("请求接口deleteUserInfo入参{}", sysAshesUserVO);
        Integer count = userSysMapper.deleteUserInfo(sysAshesUserVO);
        if (count == 0) {
            throw new AshesException("删除失败");
        }
        //统一记录结果集日志
        log.info("请求接口deleteUserInfo返回结果{}", count);
        return Result.ok(count);
    }

    @Override
    public Result updateUserStatus(SysAshesUserVO sysAshesUserVO) {
        log.info("请求接口updateUserStatus入参{}", sysAshesUserVO);
        Integer count = userSysMapper.updateUserStatus(sysAshesUserVO);
        if (count == 0) {
            throw new AshesException("修改状态失败");
        }
        //统一记录结果集日志
        log.info("请求接口updateUserStatus返回结果{}", count);
        return Result.ok(count);
    }

    @Override
    public Result checkUserInfo(SysAshesUserVO sysAshesUserVO) {
        log.info("请求接口checkUserInfo入参{}", sysAshesUserVO);
        //sysAshesUserVO.setPassword(MD5Util.encrypt(sysAshesUserVO.getPassword()));
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysAshesUserVO.getUserName(), sysAshesUserVO.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new AshesException(ResultCodeEnum.ACCOUNT_ERROR);
        }
        //使用userid生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getUserId().toString();
        String jwt = JwtUtil.createJWT(userId);
        // authenticate存入redis
        redisCache.setCacheObject("login:" + userId, loginUser);
        //把token响应给前端
        HashMap<String, String> map = new HashMap<>();
        map.put("token", jwt);

//
//        SysAshesUserPO sysAshesUserPO = userSysMapper.checkUserInfo(sysAshesUserVO);
//        String encrypt = MD5Util.encrypt(sysAshesUserVO.getPassword());
//        if (!sysAshesUserPO.getPassword().equals(encrypt)){
//            throw new AshesException("账号或密码错误");
//        }
        //统一记录结果集日志
        log.info("请求接口updateUserStatus返回结果{}", map);
        return Result.ok(map);
    }

    @Override
    public Result queryUserInfo(String id) {
        log.info("请求接口queryUserInfo入参{}", id);
        SysAshesUserPO sysAshesUserPO = userSysMapper.queryUserInfo(id);
        //统一记录结果集日志
        log.info("请求接口queryUserInfo返回结果{}", sysAshesUserPO);
        return Result.ok(sysAshesUserPO);
    }

    @Override
    public Result queryUserInfoByToken(HttpServletRequest request,String token) {
        log.info("请求接口queryUserInfoByToken入参{}", token);
        //从redis中获取用户信息
        LoginUser loginUser = RequestTokenUtil.analysisToken(token, redisCache);
        Map<String, Object> result = new HashMap<>();
        SysAshesUserPO user = loginUser.getUser();
        //根据用户id获取菜单权限值
        List<String> routerVoList = menuSysService.selectRouterByUserId(user.getUserId());
        //根据用户id获取用户按钮权限
        List<String> permsList = loginUser.getPermissions();

        result.put("name", user.getUserName());
        result.put("avatar", user.getAvatar());
        //当前权限控制使用不到，我们暂时忽略
        result.put("roles",  "00".equals(user.getUserType()) ? "管理员" : "普通用户");
        result.put("buttons", permsList);
        result.put("routers", routerVoList);
        log.info("请求接口queryUserInfoByToken返回结果{}", result);
        return Result.ok(result);
    }

    @Override
    public void logout(String token) {
        Boolean flag = RequestTokenUtil.deleteToken(token, redisCache);
        if (Boolean.FALSE.equals(flag)){
            throw new AshesException("暂时无法退出,请联系管理员");
        }
    }
}
